package com.sqi.reactive.common.controller

import com.sqi.reactive.common.service.BaseService
import io.swagger.annotations.ApiOperation
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.reactive.asFlow
import kotlinx.coroutines.runBlocking
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.ResponseBody
import reactor.core.publisher.Mono
import java.io.Serializable

/**
 * @author sjl
 * @date 2020/6/9
 */
abstract class BaseCrudController<T : Any, ID : Serializable, SERVICE : BaseService<T, *, ID>> :
    BaseQueryController<T, ID, SERVICE>() {

    @ApiOperation(value = "新增数据", notes = "此接口为通用接口")
    @PostMapping("/save")
    @ResponseBody
    fun saveEntity(@RequestBody entity: T): Mono<ResultHandler<T>> =
        resultHandler { doSaveEntity(entity) }

    open fun doSaveEntity(entity: T): Mono<T> = this.service.save(entity)

    @ApiOperation(value = "根据主键修改", notes = "此接口为通用接口")
    @PostMapping("/update/{id}")
    @ResponseBody
    fun updateEntityById(@RequestBody entity: T, @PathVariable id: ID): Mono<ResultHandler<T>> =
        resultHandler { doUpdateEntityById(entity, id) }

    open fun doUpdateEntityById(entity: T, id: ID): Mono<T> = this.service.update(entity, id)

    @ApiOperation(value = "根据主键删除", notes = "此接口为通用接口")
    @PostMapping("/delete/{id}")
    @ResponseBody
    fun deleteById(@PathVariable id: ID): Mono<ResultHandler<String?>> {
        return runBlocking {
            return@runBlocking try {
                doDeleteById(id).asFlow().collect { }
                resultHandler("SUCCESS")
            } catch (e: Exception) {
                Mono.just(ResultHandler<String?>(ResultHandler.ResultHandlerType.SYSTEM_ERROR, e.message))
            }
        }
    }

    open fun doDeleteById(id: ID): Mono<Void> = this.service.deleteById(id)
}


